<template>
  <!-- 多个标签显示 -->
  <template v-if="labelList.length > 1">
    <el-tag
      v-for="(item, index) in labelList"
      :key="index"
      :type="item.tagType || type"
      class="mr-1"
    >
      {{ item.label }}
    </el-tag>
  </template>
  <!-- 单个标签显示 -->
  <template v-else-if="label">
    <el-tag :type="tagType || type">
      {{ label }}
    </el-tag>
  </template>
  <!-- 无匹配值时，显示空或原始值 -->
  <template v-else>
    <span>{{ modelValue || '-' }}</span>
  </template>
</template>

<script setup>
/**
 * @description: 根据传入的 options 字典数据，显示对应的标签。
 * @props modelValue - 当前值，可以是单个值(String/Number)或多个值的数组/字符串。
 * @props options - 字典数据源，格式为 [{ label, value, tagType?, children? }, ...]。
 * @props type - 默认的 el-tag 类型。
 * @props separation - 当 modelValue 是字符串时，用于分割多个值的分隔符。
 */
import { ref, watch, computed } from 'vue';

// 1. 修改 Props 定义：移除 code 和 perms，新增 options
const props = defineProps({
  modelValue: [String, Number, Array],
  // 新增：直接接收字典数据数组
  options: {
    type: Array,
    default: () => [],
  },
  // 默认的 el-tag 类型
  type: {
    type: String,
    default: 'primary',
  },
  // 多值分隔符
  separation: {
    type: String,
    default: ',',
  },
});

// 2. 创建一个高效的查找映射 (Map)
// 使用 computed，当 options 变化时，map 会自动更新
const optionsMap = computed(() => {
  const map = new Map();
  // 递归函数，用于扁平化树形结构数据
  const flatten = (data) => {
    if (!data) return;
    for (const item of data) {
      map.set(String(item.value), { label: item.label, tagType: item.tagType });
      if (item.children && item.children.length > 0) {
        flatten(item.children);
      }
    }
  };
  flatten(props.options);
  return map;
});

// 3. 简化状态变量
const label = ref('');
const tagType = ref(null);
const labelList = ref([]);

// 4. 重写核心更新逻辑
const updateLabels = () => {
  // --- 值处理逻辑保持不变 ---
  let values = [];
  if (
    props.modelValue === null ||
    props.modelValue === undefined ||
    props.modelValue === ''
  ) {
    values = [];
  } else if (Array.isArray(props.modelValue)) {
    values = props.modelValue.map(String);
  } else if (typeof props.modelValue === 'string') {
    values = props.modelValue
      .split(props.separation)
      .map((v) => v.trim())
      .filter((v) => v);
  } else {
    values = [String(props.modelValue)];
  }
  // --- 值处理逻辑结束 ---

  if (values.length > 0) {
    // 直接从 map 中查找，无需异步操作
    const results = values.map((value) => {
      const entry = optionsMap.value.get(value);
      return entry || { label: value, tagType: 'info' }; // 如果找不到，返回原始值
    });

    // 根据结果数量决定渲染方式
    if (results.length > 1) {
      labelList.value = results;
      label.value = '';
      tagType.value = null;
    } else {
      label.value = results[0].label;
      tagType.value = results[0].tagType;
      labelList.value = [];
    }
  } else {
    // 清空所有状态
    label.value = '';
    tagType.value = null;
    labelList.value = [];
  }
};

// 5. 使用 watch 替代 onMounted 和 watch
// { immediate: true } 会让 watch 在组件初始化时立即执行一次，效果等同于 onMounted
watch(() => [props.modelValue, props.options], updateLabels, {
  immediate: true,
  deep: true, // 深度监听 options 的变化
});

// 设置组件名称，方便调试
defineOptions({
  name: 'RaDictLabelWithOptions',
});
</script>

<style scoped>
.mr-1 {
  margin-right: 0.25rem; /* 4px */
}
</style>
